/***************************************************************************
 * 文件名:EtConceptsManager.java<br>
 * 版本: <br>
 * 描述: <br>
 * 版权所有: <br>
 * //////////////////////////////////////////////////////// <br>
 * 创建者: robo<br>
 * 创建日期: 2010-11-10 <br>
 * 修改者: <br>
 * 修改日期: <br>
 * 修改说明: <br>
 **************************************************************************/
package com.sunwayhorizo.health.ets.base.service;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.Query;

import org.apache.commons.lang.StringUtils;
import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.dto.DictionaryDTO;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.ets.base.common.BaseDao;
import com.sunwayhorizo.health.ets.base.common.EtsConstant;
import com.sunwayhorizo.health.ets.base.persistent.EtConcepts;
import com.sunwayhorizo.health.ets.base.persistent.EtVersions;
import com.sunwayhorizo.health.ets.base.service.dao.IConceptsDao;
import com.sunwayhorizo.health.ets.dto.EtConceptsDTO;
import com.sunwayhorizo.health.ets.dto.EtVersionsDTO;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;

@Name("EtConceptsManager")
@Stateless
@SuppressWarnings("unchecked")
public class EtConceptsManager extends BaseDao implements EtConceptsManagerLocal{
	
	public ResultsDTO findEtConcepts(int currentPage,int pageSize,String conceptsName,String conceptsCode,String versionId)throws Exception{
		ResultsDTO  model = new ResultsDTO(currentPage,pageSize);
		
		String jpql = "select o from EtConcepts o,EtVersions v where o.etVersions.versionId=v.versionId ";
		Query query = getJpql(conceptsName, conceptsCode,versionId, jpql);
		if(currentPage!=0&&pageSize!=0)
		{
			query.setFirstResult(model.getBeginIndex());
			query.setMaxResults(model.getPageSize());
		}
		List<EtConcepts> list = query.getResultList();
		
		List<EtConceptsDTO> returnList = new ArrayList<EtConceptsDTO>();
		if(list != null && !list.isEmpty()) {
			for(EtConcepts ecs:list) {
				EtConceptsDTO dto = convertConceptsDTO(ecs);
				returnList.add(dto);
			}
		}
		model.setResultFlag(true);
		model.setObject(returnList);
		if(currentPage!=0&&pageSize!=0)
		{
			model.setTotalRecords(findEtConceptsCount(conceptsName,conceptsCode,versionId));
		}
		return model;
	}

	public ResultsDTO findEtConcepts(String versionId)throws Exception
	{
		List<EtConceptsDTO> roots=new ArrayList<EtConceptsDTO>();
		dto=findEtConcepts(0,0,null,null,versionId);
		if(null!=dto&&null!=dto.getObject())
		{
			List<EtConceptsDTO> returnList=(List<EtConceptsDTO>)dto.getObject();
			roots=getRoots(returnList);//获取术语项根节点列表
			if(roots.size()<1)
			{
				return dto;
			}else
			{
				dto.setObject(creatResultList(roots,returnList));
			}
		}
		return dto;
	}
	/**
	 * 为已知的根节点组装树形
	 * @param roots
	 * @param nodes
	 * @return
	 */
	private List<EtConceptsDTO> creatResultList(List<EtConceptsDTO> roots,List<EtConceptsDTO> nodes) {
		List<EtConceptsDTO> tempList=nodes;
		for(EtConceptsDTO dto:roots)
		{
			dto.setChildren(getChildren(dto.getConceptId(),tempList));
		}
		return roots;
	}

	/**
	 * 根据父节点查找子节点集合
	 * @param conceptId
	 * @param nodes
	 * @return
	 */
	private List<EtConceptsDTO> getChildren(String conceptId,List<EtConceptsDTO> nodes) {
		List<EtConceptsDTO> chs=new ArrayList<EtConceptsDTO>();
		for(int i=0;i<nodes.size();i++)
		{
			EtConceptsDTO dto=(EtConceptsDTO)nodes.get(i);
			if(conceptId.equals(dto.getParentId()))
			{
				dto.setChildren(getChildren(dto.getConceptId(),nodes));
				chs.add(dto);
			}
		}
		return chs;
	}
	
	public ResultsDTO checkUnique(EtConceptsDTO ecDto)throws Exception
	{
		EtConceptsDTO tmp=new EtConceptsDTO();
		String jpql = "select o from EtConcepts o where o.etVersions.versionId='"+ecDto.getVersionId()+"' and (o.conceptName='"+ecDto.getConceptName()+"' or o.conceptCode='"+ecDto.getConceptCode()+"')";
		Query query = entityManager2.createQuery(jpql);
		if(null!=dto)
		{
			List<EtConceptsDTO> ecDtos=convertConceptsDtos(query.getResultList());
			if(ListUtil.isNotEmpty(ecDtos))
			{
				for(EtConceptsDTO eDto:ecDtos)
				{
					if(null==eDto||eDto.getConceptId().equals(ecDto.getConceptId()))
					{
						continue;
					}
					if(StringUtils.isNotEmpty(eDto.getConceptName())&&eDto.getConceptName().equals(ecDto.getConceptName()))
					{
						tmp.setConceptName(eDto.getConceptName());
					}
					if(StringUtils.isNotEmpty(eDto.getConceptCode())&&eDto.getConceptCode().equals(ecDto.getConceptCode()))
					{
						tmp.setConceptCode(eDto.getConceptCode());
					}
				}
			}
		}
		dto.setObject(tmp);
		dto.setResultFlag(true);
		dto.setResultDesc("");
		return dto;
	}
	
	@SuppressWarnings("unused")
	private List<EtConceptsDTO> getRoots(List<EtConceptsDTO> allConcepts)
	{
		List<EtConceptsDTO> roots=new ArrayList<EtConceptsDTO>();
		if(ListUtil.isNotEmpty(allConcepts))
		{
			for(EtConceptsDTO etc:allConcepts)
			{
				if(StringUtils.isNotEmpty(etc.getVersionId())&&StringUtils.isEmpty(etc.getParentId()))
				{
					roots.add(etc);
				}
			}
		}
		return roots;
	}
	private List<EtConceptsDTO> convertConceptsDtos(List<EtConcepts> ecps)
	{
		List<EtConceptsDTO> dtos=new ArrayList<EtConceptsDTO>();
		if(ListUtil.isNotEmpty(ecps))
		{
			for(EtConcepts ec:ecps)
			{
				dtos.add(convertConceptsDTO(ec));
			}
		}
		return dtos;
	}
	
	public ResultsDTO getConceptsByCodingSchemeId(String id)throws Exception
	{
		String versionId=null;
		EtVersionsManagerLocal  evmLocal = (EtVersionsManagerLocal)Component.getInstance("EtVersionsManager");
		dto=evmLocal.findEtVersions(id, null);
		if(null!=dto&&null!=dto.getObject())
		{
			List<EtVersionsDTO> returnList = (List<EtVersionsDTO>)dto.getObject();
			if(ListUtil.isNotEmpty(returnList))
			{
				for(EtVersionsDTO dto:returnList)
				{
					if("1".equalsIgnoreCase(dto.getDefaultFlag()))
					{
						versionId=dto.getVersionId();
						break;
					}
				}
			}
			if(null!=versionId)
			{
				dto=findEtConcepts(versionId);
				dto.setResultFlag(true);
				dto.setResultDesc("操作成功！");
			}
		}else
		{
			dto.setResultErrorText("获取术语失败。");
			dto.setResultFlag(false);
		}
		return dto;
	}
	
	private EtConceptsDTO convertConceptsDTO(EtConcepts ecs) {
		EtConceptsDTO dto = new EtConceptsDTO();
		dto.setBuildNum(ecs.getBuildNum());
		dto.setConceptId(ecs.getConceptId());
		dto.setConceptCode(ecs.getConceptCode());
		dto.setConceptName(ecs.getConceptName());
		dto.setCreatedBy(ecs.getCreatedBy());
		dto.setCreatedByName(ecs.getCreatedByName());
		dto.setDomainTxt(ecs.getDomainTxt());
		dto.setWubiCode(ecs.getInputWb());
		dto.setPinyinCode(ecs.getInputPy());
		dto.setStatusCode(ecs.getStatusCode());
		dto.setRetiredDate(ecs.getRetiredDate());
		dto.setExtendedTypeCode(ecs.getExtendedTypeCode());
		dto.setLastUpdatedBy(ecs.getLastUpdatedBy());
		dto.setLastUpdatedByName(ecs.getLastUpdatedByName());
		dto.setVersionId(ecs.getEtVersions().getVersionId());
		
		//后加属性
		dto.setConceptClass(ecs.getConceptClass());
		dto.setAdministrations(ecs.getAdministrations());
		dto.setFreqCounter(ecs.getFreqCounter());
		dto.setFreqInterval(ecs.getFreqInterval());
		dto.setFreqIntervalUnit(ecs.getFreqIntervalUnit());
		dto.setDefaultSchedule(ecs.getDefaultSchedule());
		dto.setEtBlob(ecs.getEtBlob());
		dto.setEtColb(ecs.getEtClob());
		
		//质控部分后加属性
		dto.setWriteTypeDictCode( ecs.getWriteTypeDictCode() );
		dto.setMqaModelCode( ecs.getMqaModelCode() );
		dto.setIntactValue( ecs.getIntactValue() );
		dto.setIsCoexist( ecs.getIsCoexist() );
		dto.setRateHour( ecs.getRateHour() );
		dto.setPatientConditionCode( ecs.getPatientConditionCode() );
		dto.setIsEquipped( ecs.getIsEquipped() );
		dto.setAttentionRoleCode( ecs.getAttentionRoleCode() );
		dto.setAttentionMessages( ecs.getAttentionMessages() );
		dto.setMrDocumentClassCode( ecs.getMrDocumentClassCode() );
		dto.setGradeScaleStdCode( ecs.getGradeScaleStdCode() );
		dto.setIsAddUp( ecs.getIsAddUp() );
		dto.setIsAutoCount( ecs.getIsAutoCount() );
		
		if(null!=ecs.getEtConcepts()&&StringUtils.isNotEmpty(ecs.getEtConcepts().getConceptId()))
		{
			dto.setParentId(ecs.getEtConcepts().getConceptId());
		}
		return dto;
	}
	
	public ResultsDTO newEtConcepts(EtConceptsDTO dto)throws Hl7Exception {
		ResultsDTO resultsDTO = new ResultsDTO();
		if(null!=dto) {
			EtConcepts eConcepts = new EtConcepts();
			eConcepts = convertConceptsToConceptsDTO(dto,eConcepts);
			entityManager2.persist(eConcepts);
			entityManager2.flush();
			resultsDTO.setObject(eConcepts.getConceptId());
			resultsDTO.setResultFlag(true);
			resultsDTO.setResultDesc("新增术语成功");
		}
		return resultsDTO;
	}

	private EtConcepts convertConceptsToConceptsDTO(EtConceptsDTO dto,EtConcepts eConcepts) {
		
		eConcepts.setConceptCode(dto.getConceptCode());
		eConcepts.setConceptName(dto.getConceptName());
		eConcepts.setCreationDate(dto.getCreationDate());
		eConcepts.setCreatedBy(dto.getCreatedBy());
		EtVersions eVersions = entityManager2.find(EtVersions.class, dto.getVersionId());
		eConcepts.setEtVersions(eVersions);
		eConcepts.setDomainTxt(dto.getDomainTxt());
		eConcepts.setStatusCode(dto.getStatusCode());
		eConcepts.setInputPy(dto.getPinyinCode());
		eConcepts.setInputWb(dto.getWubiCode());
		if(null!=dto.getParentId())
		{
			EtConcepts etc = entityManager2.find(EtConcepts.class, dto.getParentId());
			eConcepts.setEtConcepts(etc);
		}
		eConcepts.setExtendedTypeCode(dto.getExtendedTypeCode());
		eConcepts.setLastUpdateDate(dto.getLastUpdateDate());
		eConcepts.setLastUpdatedBy(dto.getLastUpdatedBy());
		eConcepts.setLastUpdatedByName(dto.getLastUpdatedByName());
		eConcepts.setRetiredDate(dto.getRetiredDate());
		eConcepts.setConceptClass(dto.getConceptClass());
		eConcepts.setAdministrations(dto.getAdministrations());
		eConcepts.setFreqCounter(dto.getFreqCounter());
		eConcepts.setFreqInterval(dto.getFreqInterval());
		eConcepts.setFreqIntervalUnit(dto.getFreqIntervalUnit());
		eConcepts.setDefaultSchedule(dto.getDefaultSchedule());
		eConcepts.setEtBlob(dto.getEtBlob());
		eConcepts.setEtClob(dto.getEtColb());

		//质控部分
		eConcepts.setWriteTypeDictCode( dto.getWriteTypeDictCode() );
        eConcepts.setMqaModelCode( dto.getMqaModelCode() );
        eConcepts.setIntactValue( dto.getIntactValue() );
        eConcepts.setIsCoexist( dto.getIsCoexist() );
        eConcepts.setRateHour( dto.getRateHour() );
        eConcepts.setPatientConditionCode( dto.getPatientConditionCode() );
        eConcepts.setIsEquipped( dto.getIsEquipped() );
        eConcepts.setAttentionRoleCode( dto.getAttentionRoleCode() );
        eConcepts.setAttentionMessages( dto.getAttentionMessages() );
        eConcepts.setMrDocumentClassCode( dto.getMrDocumentClassCode() );
        eConcepts.setGradeScaleStdCode( dto.getGradeScaleStdCode() );
        eConcepts.setIsAddUp( dto.getIsAddUp() );
        eConcepts.setIsAutoCount( dto.getIsAutoCount() );
		return eConcepts;
	}
	
	public ResultsDTO updateEtConcepts(EtConceptsDTO ecdto)throws Hl7Exception {
		if(null!=ecdto) {
			EtConcepts et = entityManager2.find(EtConcepts.class, ecdto.getConceptId());
			et = convertConceptsToConceptsDTO(ecdto,et);
			entityManager2.merge(et);
			entityManager2.flush();
		}
		dto.setResultDesc("更新成功");
		dto.setResultFlag(true);
		return dto;
	}
	
	@SuppressWarnings("rawtypes")
	public ResultsDTO delEtConcepts(List  list) throws Hl7Exception {
		String jpql = "delete from EtConcepts o where ";
		if(list != null && !list.isEmpty()) {
			for(int i = 0; i < list.size() ; i++ ) {
				String id = (String)list.get(i);
				if(i < list.size()-1 ) {
					jpql += " o.conceptId="+id+" or ";
				} else {
					jpql += " o.conceptId="+id ;
				}
			}
			Query query = entityManager2.createQuery(jpql);
			int count = query.executeUpdate();
			if(count <= 0 ){
				dto.setResultFlag(false);
				dto.setResultDesc("删除失败");
			}
		}
		dto.setResultFlag(true);
		dto.setResultDesc("删除失败");
		return dto;
	}

	private Query getJpql(String conceptsName, String conceptsCode,String versionId, String jpql) {
		if(versionId != null && !versionId.equals("")){
			
			jpql += " and v.versionId=?1";
		}
		if(conceptsCode != null && !conceptsCode.equals("")){
			jpql += " and o.conceptCode like '%"+conceptsCode+"%'";
		}
		if(conceptsName != null && !conceptsName.equals("")){
			jpql += " and o.conceptName like '%"+conceptsName+"%'";
		}
		Query query = entityManager2.createQuery(jpql);
		
		if(versionId != null && !versionId.equals("")){
			query.setParameter(1, versionId);
		}
		return query;
	}
	
	public int findEtConceptsCount(String conceptsName,String conceptsCode,String versionId)throws Exception{
		String jpql = "select count(o.conceptId) from EtConcepts o ,EtVersions v where o.etVersions.versionId=v.versionId  ";
		Query query = getJpql(conceptsName, conceptsCode,versionId, jpql);
		List<Long> list = query.getResultList();
		if(list != null && list.size() >  0 ){
			return list.get(0).intValue();
		}
		return 0;
	}
	
	public List<EtConcepts> findEtConcepts(String versionId,String conceptCode,String conceptName)throws Exception{
		
		String jpql = "select o from EtConcepts o where 1=1  ";
		
		if(versionId != null && !versionId.equals("")){
			jpql += " and o.etVersions =：versionId ";
		}
		if(conceptCode != null && !conceptCode.equals("")){
			jpql += " and o.conceptCode like '%"+conceptCode+"%'";
		}
		if(conceptName != null && !conceptName.equals("")){
			jpql += " and o.conceptName like '%"+conceptName+"%' ";
		}
		
		Query query = entityManager2.createQuery(jpql);
		
		if(versionId != null && !versionId.equals("")){
			query.setParameter("versionId", versionId);
		}
		List<EtConcepts> list = query.getResultList();
		return list;
	}
	

	public EtVersions getEtVersion(String conceptId)throws Exception{
		if(conceptId == null || conceptId.equals("")){
			return null;
		}
		String jpql = " select ev from EtVersions ev ,EtConcepts o where ev.versionId=o.etVersions.versionId and o.conceptId=:conceptId ";
		Query query = entityManager2.createQuery(jpql);
		query.setParameter("conceptId", conceptId);
		List<EtVersions> list = query.getResultList();
		if(list != null && list.size() >  0 ){
			return (EtVersions)list.get(0);
		}
		return null;
	}
	
	public String getConceptCode()throws Exception{
		return "";
	}
	
	public String getExtendedTypeCode()throws Exception{
		return "";
	}
	
	public boolean isEquivalent(EtConcepts concept, int equivalenceType)throws Exception{
		return true;
	}
	
	public boolean  isEquivalent(EtConcepts concept, int equivalenceType, String equivalenceContext, boolean depthAllFlag)throws Exception{
		return true;
	}
	
	public List<DictionaryDTO> getConceptsObjects(String codingschemeEnName)throws Exception{
		
		if(codingschemeEnName == null || codingschemeEnName.equals("")){
			return null;
		}
		
		String jpql = "select ecs.codingschemeEnName, ecs.codingschemeChName,ecs.codingschemeOid,ev.versionName,o.conceptName ,o.conceptCode " +
		  			  "from EtCodingSchemes ecs,EtVersions ev, EtConcepts o " +
	                  "where  ecs.codingschemeId = ev.etCodingSchemes.codingschemeId and ev.versionId = o.etVersions.versionId  and and ev.defaultFlag='"+EtsConstant.V_NEW+"'  " +
	                  "and ecs.codingschemeEnName=:codingschemeEnName  order by o.conceptCode ";
		Query query = entityManager2.createQuery(jpql);
		query.setParameter("codingschemeEnName", codingschemeEnName);
		List<Object> list = query.getResultList();
		if(list == null || list.size() <= 0){
			return null;
		}
		List<DictionaryDTO> newList = getDictionaryDTO(list);
		return newList;
	}

	private List<DictionaryDTO> getDictionaryDTO(List<Object> list) {
		List<DictionaryDTO> newList = new ArrayList<DictionaryDTO>();
		for(int i = 0; i< list.size(); i++) {
			Object[] o = (Object[])list.get(i);
			DictionaryDTO dto = new DictionaryDTO();
			dto.setCodingschemeEnName((String)o[0]);
			dto.setCodingschemeChName((String)o[1]);
			dto.setCodingschemeOid((String)o[2]);
			dto.setVersionName((String)o[3]);
			dto.setConceptName((String)o[4]);
			dto.setConceptCode((String)o[5]);
			newList.add(dto);
		}
		return newList;
		
	}
	
	public List<DictionaryDTO> getConceptsObjects(String codingschemeChName,String codingschemeEnName,String versionName)throws Exception{
		
		String jpql = "select ecs.codingschemeEnName, ecs.codingschemeChName,ecs.codingschemeOid,ev.versionName,o.conceptName ,o.conceptCode " +
					  "from EtCodingSchemes ecs,EtVersions ev, EtConcepts o " +
				      "where  ecs.codingschemeId = ev.etCodingSchemes.codingschemeId and ev.versionId = o.etVersions.versionId  and ev.defaultFlag='"+EtsConstant.V_NEW+"'  ";
		
		if(codingschemeChName != null && !codingschemeChName.equals("")){
			jpql += " and ecs.codingschemeChName=:codingschemeChName ";
		}
		
		if(codingschemeEnName != null && !codingschemeEnName.equals("")){
			jpql += " and ecs.codingschemeEnName=:codingschemeEnName ";
		}
		if(versionName != null && !versionName.equals("")){
			jpql += " and ev.versionName=:versionName ";
		}
		Query query = entityManager2.createQuery(jpql);
		if(codingschemeChName != null && !codingschemeChName.equals("")){
			query.setParameter("codingschemeChName", codingschemeChName);
		}
		if(versionName != null && !versionName.equals("")){
			query.setParameter("versionName", versionName);
		}
		List<Object> list = query.getResultList();
		if(list == null || list.size() <= 0){
			return null;
		}
		List<DictionaryDTO> newList = getDictionaryDTO(list);
		return newList;
	}
	
	public ResultsDTO findEtConceptDtosByCSNameAndVersionNameAndConceptCodeAndModelCode(String codingschemeEnName,String versionName,String conceptCode,String modelCode) {
        String jpql = "select o "
                + "from EtCodingSchemes ecs left join ecs.etVersionsList as ev left join ev.etConceptsList as o "
                + "where (ev.statusCode is null or ev.statusCode ='1') and (o.statusCode is null or o.statusCode = '1' )";
        
        if (StrUtil.isNotEmpty(codingschemeEnName))
        {
            jpql += " and ecs.codingschemeEnName=:codingschemeEnName ";
        }
        if (StrUtil.isNotEmpty(versionName))
        {
            jpql += " and ev.versionName=:versionName ";
        }else{
            jpql += " and ev.defaultFlag='1' ";
        }
        if (StrUtil.isNotEmpty(conceptCode)){
            jpql += " and o.conceptCode=:conceptCode ";
        }
        if (StrUtil.isNotEmpty(modelCode)){
            jpql += " and o.mqaModelCode=:modelCode ";
        }
        
        Query query = entityManager2.createQuery(jpql);
        if (StrUtil.isNotEmpty(codingschemeEnName)) {
            query.setParameter("codingschemeEnName", codingschemeEnName);
        }
        if (StrUtil.isNotEmpty(versionName)) {
            query.setParameter("versionName", versionName);
        }
        if (StrUtil.isNotEmpty(conceptCode)) {
            query.setParameter("conceptCode", conceptCode);
        }
        if (StrUtil.isNotEmpty(modelCode)) {
            query.setParameter("modelCode", modelCode);
        }
        List<EtConcepts> etsList = query.getResultList();
        dto.setObject(convertConceptsDtos(etsList));
        dto.setResultDesc("查询成功");
        dto.setResultFlag(true);
        return dto;
    }
	
//	@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
	public List<String> findLeafDirCodeAll(String codingschemeEnName,String versionName,String conceptCode,String conceptClass) throws Hl7Exception
	{
      IConceptsDao conceptsDao = (IConceptsDao) Component.getInstance("ConceptsDao");
      List<String> list = conceptsDao.findLeafDirCodeAll(codingschemeEnName,versionName,conceptCode,conceptClass);
      return list;
	}
}
